package org.brevs.time.action;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.brevs.time.model.ProjectCategory;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

/**
 * Takes care of converting parameters into objects so they action doesn't 
 * have to.
 * 
 * @author nick
 */
public class ProjectAdminBindingInterceptor extends AbstractInterceptor {

	private static final String NEW_CATEGORY_PARAM = "new-category";
	private static final int DEFAULT_CATLIST_SIZE = 10;
	private static final String CATEGORY_PARAM_PREFIX = "category-";
	private transient Log log = LogFactory.getLog(this.getClass());

	@Override
	public String intercept(ActionInvocation invocation) throws Exception {
		
		Object untypedAction = invocation.getAction();
		if (untypedAction instanceof ProjectAdminAction) {
			ProjectAdminAction action = (ProjectAdminAction) untypedAction;
			action.setCategories(buildCategories(invocation));
		} else {
			log.error("this interceptor only works with actions of type " + ProjectAdminAction.class);
		}
		
		return invocation.invoke();
	}

	private List<ProjectCategory> buildCategories(ActionInvocation invocation) {
		Map<?, ?> parameters = invocation.getInvocationContext().getParameters();
		List<ProjectCategory> catList = 
			new ArrayList<ProjectCategory>(DEFAULT_CATLIST_SIZE);
		
		for (Entry<?, ?> entry : parameters.entrySet()) {
			final String key = (String) entry.getKey();
			if (key.equals(NEW_CATEGORY_PARAM)) {
				String[] namesOfNew = (String[]) entry.getValue();
				
				for (String name : namesOfNew) {
					ProjectCategory cat = new ProjectCategory();
					cat.setName(name);
					catList.add(cat);
				}
				
			} else if (key.startsWith(CATEGORY_PARAM_PREFIX)) {
				String idPart = key.substring(CATEGORY_PARAM_PREFIX.length());
				
				if (StringUtils.isEmpty(idPart)) {
					log.warn("category in parameters with no id");
				} else {
					Long id;
					try {
						id = new Long(idPart);
					} catch (NumberFormatException e) {
						log.warn("category with bad id - " + idPart);
						continue;
					}
					
					String[] names = (String[]) entry.getValue();
					
					if (names.length != 1) {
						log.warn("category with id " + id + " has " + names.length + " names, this should be one");
						continue;
					}
					
					ProjectCategory cat = new ProjectCategory();
					cat.setId(id);
					cat.setName(names[0]);
					catList.add(cat);
				}
			}
		}
		
		return catList;
	}

}
